#ifndef ELF_H
#define ELF_H

#include <typedef.h>



/* ELF Header */
typedef struct {
	u8 e_ident[16];
	u16 e_type;
	u16 e_machine;
	u32 e_version;
	u32 e_entry;
	u32 e_phoff;
	u32 e_shoff;
	u32 e_flags;
	u16 e_ehsize;
	u16 e_phentsize;
	u16 e_phnum;
	u16 e_shentsize;
	u16 e_shnum;
	u16 e_shstrndx;
} __attribute__ ((packed)) elf_hdr;

#define SHT_NULL 0
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
#define SHT_STRTAB 3
#define SHT_RELA 4
#define SHT_HASH 5
#define SHT_DYNAMIC 6
#define SHT_NOTE 7
#define SHT_NOBITS 8
#define SHT_REL 9
#define SHT_SHLIB 10
#define SHT_DYNSYM 11

typedef struct {
	u32 st_name;
	u32 st_value;
	u32 st_size;
	u8 st_info;
	u8 st_other;
	u16 st_shndx;
} __attribute__ ((packed)) elf_sym;

typedef struct {
	u32 sh_name;
	u32 sh_type;
	u32 sh_flags;
	u32 sh_addr;
	u32 sh_offset;
	u32 sh_size;
	u32 sh_link;
	u32 sh_info;
	u32 sh_addralign;
	u32 sh_entsize;
} __attribute__ ((packed)) elf_sh;

#define ET_EXEC 2
#define EM_386 3

/* ELF Program Header */
typedef struct {
	u32 p_type;
	u32 p_offset;
	u32 p_vaddr;
	u32 p_paddr;
	u32 p_filesz;
	u32 p_memsz;
	u32 p_flags;
	u32 p_align;
} __attribute__ ((packed)) elf_ph;

#define PT_NULL 	0
#define PT_LOAD 	1
#define PT_DYNAMIC 	2
#define PT_INTERP 	3
#define PT_NOTE 	4
#define PT_SHLIB 	5
#define PT_PHDR		6

#define PF_R	0x1
#define PF_W	0x2
#define PF_X	0x4

typedef struct {
  struct elf_info *info;
  u32 numsyms;
  elf_sym *syms;
  char *strtab;
} symtab;

typedef struct {
  struct symtab *symbols;
  elf_hdr *hdr;
  u16 shnum;
  elf_sh *sec;
  char *shstrtab;
  void *image; 
} elf_info;

#endif
